package com.timebank.timecoin.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.timebank.timecoin.pojo.entity.User;
import com.timebank.timecoin.service.ContractService;
import lombok.extern.slf4j.Slf4j;
import org.hyperledger.fabric.gateway.Contract;
import org.hyperledger.fabric.gateway.ContractException;
import org.hyperledger.fabric.gateway.Network;
import org.hyperledger.fabric.sdk.Peer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

/**
 * 智能合约服务层实现类
 * @author shiliuyinzhen
 */
@Service
@Slf4j
public class ContractServiceImpl implements ContractService {

    @Resource
    private Contract contract;

    @Resource
    private Network network;

    /**
     * 查询所有用户信息
     * @return
     * @throws ContractException
     */
    @Override
    public List<User> queryAll() throws ContractException {
        byte[] userListByte = contract.evaluateTransaction("GetAllUsers");
        List<User> userList = JSON.parseArray(userListByte,User.class);
        return userList;
    }

    /**
     * 根据id查询用户信息
     * @param userId
     * @return
     * @throws ContractException
     */
    @Override
    public User getUserById(Long userId) throws ContractException {
        byte[] userByte = contract.evaluateTransaction("ReadUser",userId.toString());
         return JSON.parseObject(userByte,User.class);
    }

    /**
     * 添加用户
     * @param user
     * @return
     * @throws ContractException
     * @throws InterruptedException
     * @throws TimeoutException
     */
    @Override
    public String createUser(User user) throws ContractException, InterruptedException, TimeoutException {
        byte[] invokeResult = contract.createTransaction("CreateUser")
                .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)))
                .submit(user.getUserId().toString(), user.getUserName(), String.valueOf(user.getTimeCoin()));
        String txId = new String(invokeResult, StandardCharsets.UTF_8);
        return txId;
    }


    /**
     * 更新用户信息
     * @param user
     * @return
     * @throws ContractException
     * @throws InterruptedException
     * @throws TimeoutException
     */
    @Override
    public String updateUser(User user) throws ContractException, InterruptedException, TimeoutException {
        byte[] invokeResult = contract.createTransaction("UpdateUser")
                .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)))
                .submit(user.getUserId().toString(), user.getUserName(), String.valueOf(user.getTimeCoin()));
        String txId = new String(invokeResult, StandardCharsets.UTF_8);
        return txId;
    }

}
